package com.domainlanguage.time;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.type.ImmutableType;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
 * Maps a timepoint to a bigint, for databases that don't have millisecond
 * precision for timestamp (MySQL for example).
 *
 */
public class BigIntTimePointType extends ImmutableType {
    @Override
    public Object get(final ResultSet rs, final String name) throws HibernateException, SQLException {
        final long longValue = rs.getLong(name);
        if (rs.wasNull()) {
            return null;
        } else {
            return TimePoint.from(longValue);
        }
    }

    @Override
    public void set(final PreparedStatement st, final Object value, final int index) throws HibernateException, SQLException {
        final TimePoint timePoint = (TimePoint) value;
        final Long millis = timePoint == null ? null : timePoint.millisecondsFromEpoc;

        Hibernate.LONG.set(st, millis, index);
    }

    @Override
    public int sqlType() {
        return Types.BIGINT;
    }

    @Override
    public String toString(final Object value) throws HibernateException {
        final TimePoint timePoint = (TimePoint) value;
        return timePoint == null ? null : String.valueOf(timePoint.millisecondsFromEpoc);
    }

    @Override
    public Object fromStringValue(final String xml) throws HibernateException {
        return TimePoint.from(Long.valueOf(xml));
    }

    @Override
    public Class getReturnedClass() {
        return TimePoint.class;
    }

    @Override
    public String getName() {
        return "timePoint";
    }
}
